#pragma once

#include <iostream>
#include <string>
#include <stdarg.h>

// 日志有日志等级
#define DEBUG   0
#define NORMAL  1
#define WARNING 2
#define ERROR   3 /* 出错了，但不影响运行 */
#define FATAL   4 /* 出错了，且不能继续运行 */

#define LOG_NORMAL  "log.normal"
#define LOG_ERROR   "log.error"


const char* to_levelstr(int level)
{
    switch(level)
    {
        case DEBUG: return "DEBUG";
        case NORMAL: return "NORMAL";
        case WARNING: return "WARNING";
        case ERROR: return "ERROR";
        case FATAL: return "FATAL";
        default: return nullptr;
    }
}

// logMessage(DEBUG, "%d %c %f", 1, 'c', 3.14);
void logMessage(int level, const char* format, ...)
{
    // 日志格式：[日志等级] [时间][PID] [MESSAGE]
    // 例如：[WARNING] [2024-04-27] [12358] ["create socket fail"]

    // TODO
    // std::cout << message << std::endl;

    // va_list start;
    // va_start(start);// 让start指向第一个参数
    // while()
    // va_arg(start, char);// 让start向后移动指定类型的大小
    // va_end(start);// 重置start为空

#define NUM 1024
    char logPrefix[NUM];// 日志前缀
    char logContent[NUM];// 日志内容
    snprintf(logPrefix, sizeof(logPrefix), "[%s][%ld][pid: %d]", to_levelstr(level), time(nullptr), getpid());/*time_t time(time_t *tloc); time_t = long int*/
    va_list arg;
    va_start(arg, format);// 函数参数压栈的顺序是从右往左
    vsnprintf(logContent, sizeof(logContent), format, arg);

    // std::cout << logPrefix << logContent << std::endl;

    FILE* log_normal = fopen(LOG_NORMAL, "a");
    FILE* log_error = fopen(LOG_ERROR, "a");
    if(log_normal && log_error)
    {
        FILE* log = nullptr;
        if(level == DEBUG || level == NORMAL || level == WARNING) log = log_normal;
        else if(level == ERROR || level == FATAL) log = log_error;
            
        fprintf(log, "%s%s\n", logPrefix, logContent);
        
        fclose(log_normal);
        fclose(log_error);
    }
}